package pogvue.gui;

import pogvue.datamodel.*;
import pogvue.gui.schemes.ColourSchemeI;
import pogvue.analysis.*;

import java.awt.*;
import java.util.*;

public class GraphBaseRenderer implements RendererI {
  public static Color sigColor = Color.red.darker();

    public Color getResidueBoxColour(ColourSchemeI cs, SequenceI seq, int i) {
	Color c = cs.findColour(seq,seq.getSequence(i,i+1),i,null);
	return c;
    }
    
    public void drawSequence(Graphics g,ColourSchemeI cs,SequenceI seq,int start, int end, int x1, int y1, double width, int height,boolean showScores, boolean displayBoxes, boolean displayText,Vector pid, int seqnum,AlignViewport av, Hashtable props, int intpid[][]) {
      SequenceI topseq = av.getAlignment().getSequenceAt(0);

	Color currentColor = Color.white;

	LinkedHashMap conf = av.getGFFConfig();


	if (seq instanceof GFF) {
	    GFF gff = (GFF)seq;

	    Vector feat = gff.overlaps(start,end);
	   
	    Vector peaks = new Vector();
	   
	    if (width > 1 && feat.size() > 0 && ((SequenceFeature)feat.elementAt(0)).getType().equals("omega")) {
		peaks = find_peaks(feat,start,end);
            }

            //System.out.println("Peaks are " + peaks.size() + " " + width);
	    for (int i = 0; i < feat.size(); i++) {

	      SequenceFeature sf = (SequenceFeature)feat.elementAt(i);
	      Color c = Color.black;

	      if (conf != null && conf.containsKey(sf.getType())) {
		c = (Color)(conf.get(sf.getType()));
		g.setColor(c);
	      } else {
		
		c = new Color((int)(Math.random()*255),(int)(Math.random()*255),(int)(Math.random()*255));
		conf.put(sf.getType(),c);
		g.setColor(c);
	      }

	      int fstart = sf.getStart();
	      int fend   = sf.getEnd();
	      
	      if (fstart < start) {
		fstart = start;
	      }
	      
	      if (fend > end) {
		fend = end+1;
	      }

	      int baseline = 0;

	      int graphWidth = 1;

	      if (width > 1) {
		  graphWidth = (int)width;
	      }

	      double mult = 0.5;
	      if (sf.getScoreVector() != null) {
		  for (int j = start; j <= end; j++) {
		      Vector score = sf.getScoreVectorAt(j);
		      double dscore = sf.getScoreAt(j);

		      //System.out.println("Score is " + j + " " + dscore);
		      int tmpy = y1;

		      int tmpheight = (int)(dscore*height/10);


		      if (score.size() == 4) {
			  double abase = ((Double)(score.elementAt(0))).doubleValue();
			  double cbase = ((Double)(score.elementAt(1))).doubleValue();
			  double gbase = ((Double)(score.elementAt(2))).doubleValue();
			  double tbase = ((Double)(score.elementAt(3))).doubleValue();
			  
			  g.setColor(Color.green);
			  
			  g.fillRect(x1 + (int)((j-start-1)*width),(int)(tmpy - mult*abase*tmpheight),graphWidth,(int)(mult*abase*tmpheight));
			  
			  tmpy = tmpy - (int)(mult*abase*tmpheight);
			  
			  g.setColor(Color.blue);
			  
			  g.fillRect(x1 + (int)((j-start-1)*width),(int)(tmpy - mult* cbase*tmpheight),graphWidth,(int)(mult*cbase*tmpheight));
			  
			  tmpy = tmpy - (int)(mult* cbase*tmpheight);
			  
			  g.setColor(Color.yellow);
			  
			  g.fillRect(x1 + (int)((j-start-1)*width),(int)(tmpy - mult*gbase*tmpheight),graphWidth,(int)(mult*gbase*tmpheight));
			  
			  tmpy = tmpy - (int)(mult*gbase*tmpheight);
			  
			  g.setColor(Color.red);
			  
			  g.fillRect(x1 + (int)((j-start-1)*width),(int)(tmpy - mult*tbase*tmpheight),graphWidth,(int)(mult*tbase*tmpheight));

			  tmpy = tmpy - (int)(mult*tbase*tmpheight);
		      }

		  }
	      } else {

		  
		  for (int j = start; j <= end; j++) {
		      double score = sf.getScoreAt(j);
		      
		      g.setColor(c);
		      
		      if (score >= 0) {
			  
			  int newscore = 0;
			  if ( sf.getType().equals("12merpvalue") ) {
			      newscore = (int)((score)*height*mult/10.0 - height);
			  } else  if ( sf.getType().equals("omega") ) {
			      newscore = (int)((score)*height - height);
			  } else {
			      newscore = (int)((score));
			  } 
			  double tmp = width;
			  int tmpj = j;

			  // if (sf.getType().equals("30mamm.euth")) {
			  //  if (score >= 14) {     //74 for 5% FDR
			  //    g.setColor(sigColor);
			  //  }
			  // }
			  //if (sf.getType().equals("30mamm.euth.6mer")) {
			  //  if (score >= 17) {     // 42 for 5% FDR
			  //    g.setColor(sigColor);
			  //  }
			  // }
			  //if (sf.getType().equals("newpi")) {
			  //  if (score >= 16) {    // 66 for 5% FDR
			  //    g.setColor(sigColor);
			  //  }
			  //    tmp = width;
			  //    tmpj += 0;
			  // }
			  if (tmp < 1) {
			      tmp = 1;
			  }
			  int itmp = (int)tmp;
			  
			  if (score >= 0) {
			      g.fillRect(x1+(int)((tmpj-start-1)*width),(int)(y1 - newscore), itmp, (newscore));
			  }
		      }
		  }
		  
		  g.setColor(Color.white);
		  g.fillRect(x1+(int)(width),(int)(y1 + height+1), (int)((end-start+1)*width), height+2);
		  g.setColor(Color.black);
		  for (int j = 0; j < peaks.size(); j++) {
                      int coord = ((Integer)peaks.elementAt(j)).intValue();
		      
		      g.fillRect(x1+(int)((coord-start-1)*width+width/2),(int)(y1-height+1), (int)(1), height+2);
		      
		      g.setColor(Color.black);
		      // We're fixed to a 12mer currently
		      
		      Vector seqhashvec = AAFrequency.calculate(av.getAlignment().getSequences(),coord-6,coord+6);
		      
		      for (int k = 0; k < 12; k++) {
			  Hashtable seqhash = (Hashtable)seqhashvec.elementAt(k);
			  String topchar = (String)seqhash.get("maxResidue");
			  
			  String ch = topseq.getSubstring(coord-6+k,coord-6+k+1);
			  
			  int topcount = ((Integer)seqhash.get("maxCount")).intValue();
			  
			  if (topchar.equals(ch)) {
			      if (topcount > 10) {
				  g.setColor(Color.black);
			      } else {
				  g.setColor(Color.blue);
			      }
			   } else {
			       g.setColor(Color.black);
			   }
			  g.drawString(ch,x1+(int)((coord-6+k-start)*width),(int)(y1+height-1));
		      }
		  }

              }
	    }
	}
    }
    public Vector find_peaks(Vector feat,int start, int end) {
       Vector peaks = new Vector();

       int win = 5;

       //System.out.println("Finding peaks");
       for (int ii = 0;ii < feat.size(); ii++) {

	  SequenceFeature f = (SequenceFeature)feat.elementAt(ii);

          for (int i = start; i <= end ; i++) {
	 
            if (i > start + 2*win+1 && i < start + (end-start-win)) {

              double score = f.getScoreAt(i);

              if (score > 0) {
		  //System.out.println("Score " + i + " " + f.getType() + " " + score);

              int ismax   = 1;

              for (int j = i-win; j < i+win; j++) {
	          double newscore = f.getScoreAt(j);

                  //System.out.println("NewScore " + f.getType() + " " + newscore);

                  if ( j != i && (newscore - score) > 0) {
		     ismax = 0;
		     j= i+win;
                  }
              }
              if (ismax == 1) {
		  //System.out.println("Adding peak " + i);
	         peaks.addElement(new Integer(i));
              }
	      }
	   }
	  } 
	}
	return peaks;
     }
}
